package com.yan.demo4;

import com.yan.demo2.Book;
import org.junit.jupiter.api.Test;

import java.io.BufferedReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.locks.Condition;

/**
 * @author taoge
 * @Date 2024/8/14 16:41
 * @Description
 */
public final class MyJson {
    // 将对象转化为字符串
    public static String toJsonString(Object obj)  {
        //原 Book{name='水浒传', author='yft', price=19.9, createDate=Wed Aug 14 16:47:22 HKT 2024}
        //{"author":"yft","createDate":1723625156831,"name":"水浒传","price":19.9}
        StringBuffer sb = null;
        try {
            if(obj == null){
                return "{}";
            }

            Class c = obj.getClass();
            sb = new StringBuffer();

            sb.append("{");
            Field[] declaredFields = c.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                declaredField.setAccessible(true);
                String fieldKey = declaredField.getName();
                fieldKey = "\"" + fieldKey + "\"";
                Object fileValue = declaredField.get(obj);
                if(fileValue instanceof String || fileValue instanceof StringBuffer || fileValue instanceof StringBuilder){
                    fileValue = "\"" + fileValue + "\"";
                }else if(fileValue instanceof Date){
                    fileValue = ((Date) fileValue).getTime();
                }
                sb.append(fieldKey + ":" + fileValue + ",");
            }
            sb.deleteCharAt(sb.length() - 1);
            sb.append("}");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }
    // 将集合对象转化为String字符串
    public static String toJsonArrayString(Object obj){
        //[{"author":"yft","createDate":1723632106054,"name":"水浒传","price":19.9},{"author":"wl","createDate":1723632106054,"name":"三国演义","price":29.9}]
        StringBuffer sb = new StringBuffer();
        try {
            Collection list = (Collection) obj;
            if(obj == null || list.size() == 0){
                throw new IllegalArgumentException("数据不合理");
            }
            sb.append("[");
            for (Object o : list) {
                String str = toJsonString(o);// {"author":"yft","createDate":1723632106054,"name":"水浒传","price":19.9}
                sb.append(str + ",");
            }
            sb.deleteCharAt(sb.length() - 1);
            sb.append("]");
            return sb.toString();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
        return "";
    }

    // 将一个对象(普通对象|集合对象) 转为：JSON字符串
    public static String objectToJsonString(Object obj){
        if(obj instanceof Map){
            throw new IllegalArgumentException("不支持Map集合");
        }
        if(obj instanceof Collection){
           return toJsonArrayString(obj);
        }
        return toJsonString(obj);
    }

    // 将一个对象的JSON字符串 解析成： Java对象          ??????
    public static <T> T jsonStringToDomain (String str , Class<T> c) throws Exception {
        // {"name":"红楼梦","author":"hpy","price":39.9,"createDate":1723633372980}

        str = str.replaceAll("\\{|\\}" , ""); //"name":"红楼梦","author":"hpy","price":39.9,"createDate":1723633372980
        String[] split = str.split(",");

        Constructor<T> cons = c.getConstructor();
        T t = cons.newInstance();
        for (String keyValue : split) {
            // 取出键值
            String[] splitArr = keyValue.split(":");
            // 单独取出键值
            String fieldName = splitArr[0].replace("\"","");
            String fieldValue = splitArr[1].replace("\"","");
            // 取出类中的每一个属性
            Field[] declaredFields = c.getDeclaredFields();
            // 循环属性
            for (Field declaredField : declaredFields) {
                declaredField.setAccessible(true);
                if(declaredField.getName().equals(fieldName)){
                    // 列出可能的情况
                    if (declaredField.getGenericType().getTypeName().contains("String")) {
                        declaredField.set(t, fieldValue);
                    } else if (declaredField.getGenericType().getTypeName().contains("Date")) {
                        long l = Long.parseLong(fieldValue);
                        Date dateFieldValue = new Date(l);
                        declaredField.set(t, dateFieldValue);
                    } else if (declaredField.getGenericType().getTypeName().contains("Double") || declaredField.getGenericType().getTypeName().contains("double")) {
                        double doubleFieldValue = Double.parseDouble(fieldValue);
                        declaredField.set(t, doubleFieldValue);
                    }else if(declaredField.getGenericType().getTypeName().contains("Integer")||declaredField.getGenericType().getTypeName().contains("int")){
                        int InterageValue = Integer.parseInt(fieldValue);
                        declaredField.set(t , InterageValue);
                    }else{
                        // "book":{"author":"hpyhpy","createDate":1723681840710,"name":"红楼梦","price":39.9},"name":"yft"
                        // fieldName = "book"
                        // fieldValue ="author":"hpyhpy","createDate":1723681840710,"name":"红楼梦","price":39.9

                        Object o = jsonStringToDomain(fieldValue, Class.forName(declaredField.getGenericType().getTypeName()));
                        declaredField.set(t,o);
                    }
                }
            }
        }

        return t;
    }


    // 将一个对象的JSON字符串集合 转换成 ： JAVA集合对象

    public static <T> Collection<T> JsonStringArrayToDomain(String str , Class<T> c){
        //[{"author":"yft1","createDate":1723712566394,"name":"三国演义1","price":29.9},{"author":"yft2","createDate":1723712566394,"name":"三国演义2","price":39.9}]
        try {
            if(str == null){
                return null;
            }
            if(c == null){
                throw new IllegalArgumentException();
            }

            str = str.replaceAll("\\[|\\]" ,"").trim();
            String[] split = str.split("\\}\\,\\{");
            split[0] = split[0] + "}";
            for (int i = 1; i < split.length - 1; i++) {
                split[i] = "{" + split[0] + "}";
            }
            split[split.length -1] ="{" + split[split.length - 1];

            LinkedList<T> t = new LinkedList<>();
            for (String s : split) {
                T e = jsonStringToDomain(s , c);
                t.add(e);
            }
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
